﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Net.NetworkInformation;

namespace Jiuyong
{
	public class Program
	{
		static void Main(string[] args)
		{
			var rf = @"scz.xml";
			var sf = "new.xml";
			var xml = XDocument.Load(rf);
			var rs = (from r in xml.Descendants("{urn:schemas-microsoft-com:office:spreadsheet}Row").Skip(1)
					 select r)
#if DEBUG
					 //.Take(100)
#endif
					 .ToArray();
			int sn = 0;//发送计数。
			int rn = 0;//返回计数。
			int sleep = 0;//睡眠单位。
			//int step = 0;//并发任务数。
			//int taskLimit = 3;//并发任务限制。
			Console.WriteLine("将处理 {0} 条记录，处理完成后结果将保存到同目录的 {1} 文件中。",rs.Length,sf);
			//var nc = new Dictionary<string,XElement>();//被取消的。
			//var ne = new Dictionary<string,XElement>();//有错误的。
			var nr = new Dictionary<string,XElement>();//无返回的。
			var na = new Dictionary<string,XElement>();//返回，但是无地址的。
			var no = new Dictionary<string,XElement>();//返回地址，但是地址无效的。
			var startTime = DateTime.Now;
			foreach (var r in rs)
			{
				var ds = r.Descendants("{urn:schemas-microsoft-com:office:spreadsheet}Data").ToArray();
				//var row = new XElement(XName.Get("{urn:schemas-microsoft-com:office:spreadsheet}Row"));
				var cell = new XElement(XName.Get("{urn:schemas-microsoft-com:office:spreadsheet}Cell"));
				var att = new XAttribute(XName.Get("{urn:schemas-microsoft-com:office:spreadsheet}Type"),"String");
				var data = new XElement(XName.Get("{urn:schemas-microsoft-com:office:spreadsheet}Data"));
				data.Value = "0.0.0.0";
				data.Add(att);
				cell.Add(data);
				//row.Add(data);
				r.Add(cell);
				var url = ds[1].Value;

				var ping = new Ping();

				//同步
				//var pr = ping.Send(url);
				//var rt = "超时！";
				//if (pr.Address == null)
				//{

				//}
				//else
				//{
				//    rt = pr.Address.ToString();
				//}
				//data.Value = rt;
				//Console.WriteLine(i + "	" + rt + "<<" + url);

				//异步
				ping.PingCompleted += (s,e) =>
				{
					string rep = "无应答，请手动重试！";
					string rpt = " * ";
					//if (e.Cancelled)
					//{
					//    nc[url] = data;
					//}
					//else if (e.Error!=null)
					//{
					//    ne[url] = data;
					//}
					//else 
					if (null==e.Reply)
					{
						nr[url]=data;
					}
					else if (null==e.Reply.Address)
					{
						na[url]=data;
					}
					else
					{
						rep = e.Reply.Address.ToString();
						rpt = e.Reply.RoundtripTime.ToString()+"ms";
					}

					if ("0.0.0.0"==rep)
					{
						no[url]=data;
					}

					data.Value = rep;
					//Console.WriteLine("总数："+rn++ +"	序号："+ ((int)e.UserState).ToString() + "	" + rep + "<<" + url);
					rn++;
					Console.WriteLine(TextLimit( String.Format("{0}	<< {4}	{1}	({2})",e.UserState,rep,url,sleep,rpt)));
					//Console.WriteLine(((int)e.UserState).ToString() + "	<<	" + rep + "	(" + url+")");
					//sleep = sleep / step + 1;
					sleep >>= 1;
					//step--;
				};
				//Console.WriteLine(sn++.ToString()+"	>>	({0}ms)	"+url);
				Console.WriteLine(TextLimit( String.Format("{0}	>> {2}	{1}",sn++,url,sleep)));
				//Console.Write("==>{0}ms",sleep,step,DateTime.Now);

				//var sleep = 100 * (2 << step + 1) - 10000;
				System.Threading.Thread.CurrentThread.Join(sleep);
				ping.SendAsync(url,sn);
				sleep =(sleep <<1)+1;
				//step++;
			}
			//Console.WriteLine("稍等 30 秒。。。等待可能返回的响应。");
			System.Threading.Thread.CurrentThread.Join(30000);
			var endTime = DateTime.Now;
			Console.WriteLine("共计处理 {0} 条记录完成,共耗时 {2:mm\\:ss} ，处理结果将保存在 {1} 文件中。",rn,sf,endTime-startTime);

			xml.Save(sf);
			Console.WriteLine("其中 无回显 {0} 条，无地址 {1} 条，空地址（0.0.0.0）{2} 条。",nr.Count,na.Count,no.Count
				//被取消 {3} 条，有错误 {4} 条，,nc.Count,ne.Count
				);
			Console.WriteLine("按回车键退出程序！");
			Console.Read();
		}

		public static string TextLimit(string text)
		{
			string r;
			if (null==text||text.Length<60)
			{
				r = text;
			}
			else
			{
				r = text.Substring(0,57) + "...";
			}
			return r;
		}

	}
}
